// Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.

// 重启任务
package reload

import (
	"github.com/pkg/errors"

	"scase.io/application-auto-scaling-service/pkg/db"
	"scase.io/application-auto-scaling-service/pkg/metricmonitor/interfaces"
	"scase.io/application-auto-scaling-service/pkg/taskmgmt"
	"scase.io/application-auto-scaling-service/pkg/taskmgmt/asynctask"
	"scase.io/application-auto-scaling-service/pkg/utils"
)

// AddAsyncTask 重启异步任务
func AddAsyncTask(monitor interfaces.MonitorInf, taskMgmt *taskmgmt.AsyncTaskMgmt, task *db.AsyncTask) error {
	if err := reloadASTask(monitor, taskMgmt, task); err != nil {
		return err
	}
	if err := reloadECSTask(monitor, taskMgmt, task); err != nil {
		return err
	}
	if err := reloadPodTask(monitor, taskMgmt, task); err != nil {
		return err
	}
	return nil
}

func reloadASTask(monitor interfaces.MonitorInf, taskMgmt *taskmgmt.AsyncTaskMgmt, task *db.AsyncTask) error {
	switch task.TaskType {
	// as group
	case db.TaskTypeScaleOutScalingGroup:
		taskConf := &db.ScaleOutTaskConf{}
		if err := utils.ToObject([]byte(task.TaskConf), taskConf); err != nil {
			return errors.Wrapf(err, "utils unmarshal task conf[%s] err", task.TaskConf)
		}
		taskMgmt.AddTask(asynctask.NewScaleOutTask(task.TaskKey, taskConf.TargetInstanceNumber))
	case db.TaskTypeScaleInScalingGroup:
		taskConf := &db.ScaleInTaskConf{}
		if err := utils.ToObject([]byte(task.TaskConf), taskConf); err != nil {
			return errors.Wrapf(err, "utils unmarshal task conf[%s] err", task.TaskConf)
		}
		taskMgmt.AddTask(asynctask.NewScaleInTask(task.TaskKey, taskConf.ScaleInInstanceIds))
	case db.TaskTypeDeleteScalingGroup:
		taskConf := &db.DeleteScalingGroupTaskConf{}
		if err := utils.ToObject([]byte(task.TaskConf), taskConf); err != nil {
			return errors.Wrapf(err, "utils unmarshal task conf[%s] err", task.TaskConf)
		}
		taskMgmt.AddTask(asynctask.NewDelScalingGroupTask(task.TaskKey, monitor))
	}
	return nil
}

func reloadECSTask(monitor interfaces.MonitorInf, taskMgmt *taskmgmt.AsyncTaskMgmt, task *db.AsyncTask) error {
	switch task.TaskType {
	case db.TaskTypeDeleteVm:
		taskConf := &db.DeleteVmTaskConf{}
		if err := utils.ToObject([]byte(task.TaskConf), taskConf); err != nil {
			return errors.Wrapf(err, "utils unmarshal task conf[%s] err", task.TaskConf)
		}
		taskMgmt.AddTask(asynctask.NewDelVmTask(task.TaskKey, taskConf.ProjectId, taskConf.GroupId))
	case db.TaskTypeScaleOutEcsGroup:
		taskmgmt.GetTaskMgmt().AddTask(asynctask.NewEcsScaleOutTask(task.TaskId, task.TaskKey))
	case db.TaskTypeScaleInEcsGroup:
		taskConf := &db.ScaleInTaskConf{}
		if err := utils.ToObject([]byte(task.TaskConf), taskConf); err != nil {
			return errors.Wrapf(err, "utils unmarshal task conf[%s] err", task.TaskConf)
		}
		taskmgmt.GetTaskMgmt().AddTask(asynctask.NewEcsScaleInTask(task.TaskId, task.TaskKey, taskConf.ScaleInInstanceIds))
	case db.TaskTypeDeleteEcsScalingGroup:
		taskConf := &db.DeleteScalingGroupTaskConf{}
		if err := utils.ToObject([]byte(task.TaskConf), taskConf); err != nil {
			return errors.Wrapf(err, "utils unmarshal task conf[%s] err", task.TaskConf)
		}
		taskMgmt.AddTask(asynctask.NewDelEcsScalingGroupTask(task.TaskKey))
	}
	return nil
}

func reloadPodTask(monitor interfaces.MonitorInf, taskMgmt *taskmgmt.AsyncTaskMgmt, task *db.AsyncTask) error {
	switch task.TaskType {
	case db.TaskTypeDeleteNamespace:
		taskmgmt.GetTaskMgmt().AddTask(asynctask.NewEcsScaleOutTask(task.TaskId, task.TaskKey))
	case db.TaskTypeScaleInPodGroup:
		taskConf := &db.ScaleInTaskConf{}
		if err := utils.ToObject([]byte(task.TaskConf), taskConf); err != nil {
			return errors.Wrapf(err, "utils unmarshal task conf[%s] err", task.TaskConf)
		}
		taskmgmt.GetTaskMgmt().AddTask(asynctask.NewPodScaleInTask(task.TaskId, task.TaskKey, taskConf.ScaleInInstanceIds))
	case db.TaskTypeDeletePodGroup:
		taskmgmt.GetTaskMgmt().AddTask(asynctask.NewDelPodNamespaceTask(task.TaskKey))
	case db.TaskTypeDeletePod:
		taskConf := &db.DeletePodTaskConf{}
		if err := utils.ToObject([]byte(task.TaskConf), taskConf); err != nil {
			return errors.Wrapf(err, "utils unmarshal task conf[%s] err", task.TaskConf)
		}
		taskMgmt.AddTask(asynctask.NewDelPodTask(task.TaskKey, taskConf.ProjectId, taskConf.GroupId))
	}
	return nil
}
